package com.reger.l2cache.pipeline.config;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.data.redis.connection.RedisConnectionFactory;

import com.reger.l2cache.pipeline.core.PipelineCore;
import com.reger.l2cache.pipeline.core.RedisPipelineCore;
import com.reger.l2cache.pipeline.pipe.BytesRedisPipeline;
import com.reger.l2cache.pipeline.pipe.IntegerRedisPipeline;
import com.reger.l2cache.pipeline.pipe.JackjsonRedisPipeline;
import com.reger.l2cache.pipeline.pipe.RedisPipeline;
import com.reger.l2cache.pipeline.pipe.StringRedisPipeline;
import com.reger.l2cache.properties.RedisPipelineProperties;

@Configuration
@EnableConfigurationProperties(RedisPipelineProperties.class)
public class RedisPipelineAutoConfiguration {

	private @Autowired RedisPipelineProperties pipelineProperties;

	@ConditionalOnMissingBean(PipelineCore.class)
	public @Bean(destroyMethod = "stop") PipelineCore pipelineCore(RedisConnectionFactory connectionFactory) {
		Integer workThreadNum = pipelineProperties.getWorkThreadNum();
		Boolean pipeEnabled = pipelineProperties.isPipeEnabled();
		return RedisPipelineCore.start(connectionFactory, pipeEnabled, workThreadNum);
	}

	public @Bean @Primary RedisPipeline<?, ?, ?> redisPipeline(PipelineCore pipelineCore) {
		return new RedisPipeline<>(pipelineCore);
	}

	public @Bean BytesRedisPipeline bytesRedisPipeline(PipelineCore pipelineCore) {
		return new BytesRedisPipeline(pipelineCore);
	}

	public @Bean StringRedisPipeline stringRedisPipeline(PipelineCore pipelineCore) {
		return new StringRedisPipeline(pipelineCore);
	}

	public @Bean IntegerRedisPipeline integerRedisPipeline(PipelineCore pipelineCore) {
		return new IntegerRedisPipeline(pipelineCore);
	}

	public @Bean JackjsonRedisPipeline<?> jackjsonRedisPipeline(PipelineCore pipelineCore) {
		return new JackjsonRedisPipeline<>(pipelineCore);
	}
}
